package me.linczh.framework.action;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public abstract class ActionExecutor {
	protected HttpSession session;
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void execute(ServletRequest request, ServletResponse response, ActionItem item) {
		String ActionMethod = item.getActionMethod();
		Map<String, Map> results = item.getResultMap();

		try {
			Map<String, String[]> params = request.getParameterMap();
			for (String pName : params.keySet()) {
				String mName = "set" + pName.substring(0, 1).toUpperCase() + pName.substring(1);
				Field pField = this.getClass().getDeclaredField(pName);
				Method setter = this.getClass().getMethod(mName, pField.getType());
				Constructor<?> cons = pField.getType().getConstructor(String.class);
				Object[] args = {cons.newInstance(params.get(pName)[0])};
				setter.invoke(this, args);
			}
			
			Method method = this.getClass().getMethod(ActionMethod);
			session = ((HttpServletRequest)request).getSession();
			String resultStr = (String)method.invoke(this, (Object[])null);
			Map<String, String> rMap = results.get(resultStr);
			
			Field[] fields = this.getClass().getDeclaredFields();
			for (Field f : fields) {
				String mName = "get" + f.getName().substring(0, 1).toUpperCase() + f.getName().substring(1);
				Method getter = this.getClass().getMethod(mName);
				((HttpServletRequest)request).setAttribute(f.getName(), getter.invoke(this, (Object[])null));
			}
			String path = ((HttpServletRequest)request).getContextPath();
			String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path;
			if (rMap.get("type").equals("json")) {
				
			} else if (rMap.get("type").equals("page")) {
				System.out.println("forward to: " + basePath + rMap.get("result"));
				request.setAttribute("contentpage", rMap.get("result"));
				RequestDispatcher view = request.getRequestDispatcher("/");
				view.forward(request, response);
			} else {
				System.out.println("redirect to: " + basePath + rMap.get("result"));
				((HttpServletResponse)response).sendRedirect(basePath + rMap.get("result"));
			}
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ServletException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public HttpSession getSession() {
		return session;
	}
}
